package com.wzcl.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.wzcl.app.dao.model.Activity;
import com.wzcl.app.dao.model.TopicInfo;
import com.wzcl.app.dao.model.TopicOption;
import com.wzcl.app.dao.repository.TopicOptionRepository;
import com.wzcl.app.model.common.BusinessException;
import com.wzcl.app.model.common.CodeMsg;
import com.wzcl.app.model.common.MyPage;
import com.wzcl.app.model.dto.TopicOptionDto;
import com.wzcl.app.service.TopicInfoService;
import com.wzcl.app.service.TopicOptionService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Log4j2
@Service
public class TopicOptionServiceImpl implements TopicOptionService {

    @Autowired
    private TopicOptionRepository repository;

    @Autowired
    private TopicInfoService topicInfoService;


    @Override
    public TopicOption addTopicOption(TopicOptionDto topicOptionDto) {
        //校验获取
        TopicInfo topicInfo = topicInfoService.getAndCheckById(topicOptionDto.getTopicInfoId());
        //创建
        TopicOption topicOption = new TopicOption();
        BeanUtils.copyProperties(topicOptionDto, topicOption, "id");
        topicOption.setTopicInfo(topicInfo);
        return repository.save(topicOption);
    }

    @Override
    public TopicOption delTopicOptionById(Integer id) {
        //校验获取
        TopicOption topicOption = getAndCheckById(id);
        //删除
        log.info("TopicOption:{} Physical deletion", JSON.toJSONString(topicOption));
        repository.delete(topicOption);
        return topicOption;
    }

    @Override
    public TopicOption updateTopicOption(TopicOptionDto topicOptionDto) {
        //校验获取
        TopicOption topicOption = getAndCheckById(topicOptionDto);
        //修改
        BeanUtils.copyProperties(topicOptionDto, topicOption, "id", "topicInfoId");
        return repository.save(topicOption);
    }

    @Override
    public TopicOption getTopicOptionById(Integer id) {
        return repository.findById(id).orElse(null);
    }


    @Override
    public TopicOption getAndCheckById(Integer id) {
        if (id == null) {
            throw new BusinessException(CodeMsg.COMMODITY_NOT_EXIST, "缺少题目选项Id");
        }
        TopicOption topicOption = getTopicOptionById(id);
        if (topicOption == null) {
            throw new BusinessException(CodeMsg.TOPIC_OPTION_NOT_EXIST);
        }
        return topicOption;
    }

    @Override
    public List<TopicOption> getTopicOptionList(TopicOptionDto topicOptionDto) {
        return repository.findAll(getSpecification(topicOptionDto), topicOptionDto.getSort());
    }

    @Override
    public MyPage<TopicOption> getTopicOptionPage(TopicOptionDto topicOptionDto) {
        Page<TopicOption> all = repository.findAll(getSpecification(topicOptionDto), topicOptionDto.getPageable());
        ArrayList<TopicOption> list = new ArrayList<>(all.getContent());
        Collections.reverse(list);
        MyPage<TopicOption> myPage = new MyPage<>();
        myPage.setContent(list);
        myPage.setTotalElements(all.getTotalElements());
        return myPage;
    }

    private Specification<TopicOption> getSpecification(TopicOptionDto topicOptionDto) {
        return new Specification<TopicOption>() {
            @Override
            public Predicate toPredicate(Root<TopicOption> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                if (topicOptionDto.getTopicInfoId() != null) {
                    Join<TopicOption, TopicInfo> topicInfoPath = root.join("topicInfo");
                    predicates.add(criteriaBuilder.equal(topicInfoPath.get("id"), topicOptionDto.getTopicInfoId()));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }

}
